package com.sxpi.zixun.service.category;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sxpi.zixun.bo.CategoryBo;
import com.sxpi.zixun.common.enums.ResultStatusEnum;
import com.sxpi.zixun.common.ex.PugValidatorException;
import com.sxpi.zixun.common.utils.fn.asserts.Vsserts;
import com.sxpi.zixun.mapper.CategoryMapper;
import com.sxpi.zixun.pojo.Category;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 董伟豪
 * @Date: 2022/9/1 9:33
 */
@Service
public class ICategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {

    /**
     * 查询管理分类
     * @param
     * @return
     */
    @Override
    public List<CategoryBo> findCategoryTree(String keyword) {
        LambdaQueryWrapper<Category> categoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        categoryLambdaQueryWrapper.like(Vsserts.isNotEmpty(keyword),Category::getTitle,keyword);
        List<Category> allList = this.list(categoryLambdaQueryWrapper);
        List<CategoryBo> categoryBos = tranferListBo(allList, CategoryBo.class);
        // 找到所有的根节点 pid = 0
        List<CategoryBo> rootList = categoryBos.stream().filter(category -> {
            return category.getPid().equals(0L);
        }).sorted((a,b)->a.getSorted()-b.getSorted()).collect(Collectors.toList());
        List<CategoryBo> subList = categoryBos.stream().filter(category -> {
            return !category.getPid().equals(0L);
        }).collect(Collectors.toList());
        rootList.forEach(root->{
            buckForback(root,subList);
        });
        return rootList;
    }

    /**
     * 保存和修改文章分类管理
     * @param category
     * @return
     */
    @Override
    public CategoryBo saveUpdateCategory(Category category) {
        boolean flag = this.saveOrUpdate(category);
        return flag ? tranferBo(category,CategoryBo.class) : null;
    }

    /**
     * 只能删除两级，递归删除得去 findCategoryTreeByPid()
     * 根据文章分类管理id删除文章分类管理
     * 写了事务的方法一定不能加try{}catch
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteCategoryById(Long id) {
        LambdaQueryWrapper<Category> categoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 全部的数据
        List<Category> allList = this.list(categoryLambdaQueryWrapper);
        // 需要删除数据
        Category category = this.getById(id);
        allList.forEach(root-> buckForbackDelete(root,category));
        // 删除本体
        Category newCategory = new Category();
        newCategory.setId(id);
        newCategory.setIsdelete(1);
        this.updateById(newCategory);
        return 0;
    }

    /**
     * 只能删除两级
     * @param root 全部数据
     * @param category 删除数据
     */
    private void buckForbackDelete(Category root, Category category) {
        // 获取到删除项的所有子集
        boolean flag = root.getPid().equals(category.getId());
        if(flag){
            Category newCategory = new Category();
            newCategory.setId(root.getId());
            newCategory.setIsdelete(1);
            this.updateById(newCategory);
        }
    }


    /**
     * 根据id找到所有孙子元素包含自己
     * 主要是为了进行批量删除
     * @method: findCategoryList
     * @result : List<CategoryBo>
     * 创建人:yykk
     * 创建时间：2022-05-23 14:38:43
     * @version 1.0.0
     * @return
     */
    public List<Category> findCategoryTreeByPid(Long pid){
        // 1 :查询表中所有的数据
        LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<Category> allList = this.list(lambdaQueryWrapper); // 思考空间，为什么查询的是所有
        List<Category> resultList = new ArrayList<>();
        // 2: 找到所有的根节点 pid = 0
        List<Category> rootList = allList.stream().filter(item->item.getId().equals(pid)).collect(Collectors.toList());
        // 4 : 循环根节点去subList去找对应的子节点
        rootList.forEach(root -> {
            resultList.add(root);
            buckForbackByPid(resultList,root, allList);
        });
        return resultList;
    }


    private void buckForbackByPid( List<Category> rootList , Category root, List<Category> subList) {
        // 通过根节点去id和子节点的pid是否相等，如果相等的话，代表是当前根的子集
        List<Category> childrenList = subList.stream().filter(category -> category.getPid().equals(root.getId()))
                .sorted((a, b) -> a.getSorted() - b.getSorted())
                .collect(Collectors.toList());
        // 如果你当前没一个子集，初始化一个空数组
        if (!CollectionUtils.isEmpty(childrenList)) {
            // 查询以后放回去
            rootList.addAll(childrenList);
            // 再次递归构建即可
            childrenList.forEach(category -> buckForbackByPid(rootList,category, subList));
        }
    }

    /**
     * 根据文章分类管理id删除文章分类管理
     * 写了事务的方法一定不能加try{}catch
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Deprecated
    public int deleteCategoryByIdDeprecated(Long id) {
        Category category = this.getById(id);
        if(category != null){
            Category category1 = new Category();
            category1.setId(category.getId());
            category1.setIsdelete(1);
            this.updateById(category1);
            return 1;
        }
        return 0;
    }

    /**
     * 根据文章分类管理ids批量删除文章分类管理
     * @param batchIds
     * @return
     */
    @Override
    public boolean deleteBatchCategory(String batchIds) {
        try {
            String[] split = batchIds.split(",");
            List<Category> categoryList = Arrays.stream(split).map(idStr -> {
                Category category = new Category();
                category.setId(new Long(idStr));
                category.setIsdelete(1);
                return category;
            }).collect(Collectors.toList());
            return this.updateBatchById(categoryList);
        } catch (Exception ex) {
            throw new PugValidatorException(ResultStatusEnum.SERVER_DB_ERROR);
        }
    }

    private void buckForback(CategoryBo root, List<CategoryBo> subList) {
        List<CategoryBo> childrenList = subList.stream().filter(category -> {
            return category.getPid().equals(root.getId());
        }).sorted((a,b)->a.getSorted()-b.getSorted()).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(childrenList)){
            root.setChildren(childrenList);
            childrenList.forEach(category -> {
                buckForback(category,subList);
            });
        }else{
            root.setChildren(new ArrayList<>());
        }
    }


}
